package com.acidsweet.zerolrucache.core.impl;


import com.acidsweet.zerolrucache.core.CacheEvent;
import com.acidsweet.zerolrucache.core.ILruCache;
import com.acidsweet.zerolrucache.core.OnEventListener;
import com.acidsweet.zerolrucache.util.Logger;
import com.acidsweet.zerolrucache.util.cache.AndroidMemoryLruCache;

/**
 * Created by jin on 16/8/2.
 */
public class MemoryLruCache extends ILruCache {
    private static final String TAG=MemoryLruCache.class.getSimpleName();
    /**
     * Use LruCache here as Cache
     * ONLY Object which can convert to byte[] can be stored
     */
    private AndroidMemoryLruCache<String,byte[]> mCache;

    @Override
    public void init() {
        Logger.d(TAG,"init");
        mCache=new AndroidMemoryLruCache<String,byte[]>(mMaxSize){
            @Override
            protected int sizeOf(String key, byte[] value) {
                return value.length;
            }
        };
    }

    @Override
    public void put(String key, byte[] value,OnEventListener listener) {
        Logger.d(TAG,"put key="+key);
        try {
            Logger.d(TAG,"put 0 key="+key);
            mCache.put(key, value);
            Logger.d(TAG,"put 1 key="+key);
            CacheEvent event=new CacheEvent();
            event.isSucc=true;
            event.action=CacheEvent.ACTION_PUT;
            event.key=key;
            event.value=value;
            OnActionSucc(listener,event);
            Logger.d(TAG,"put 2 key="+key);
        }catch (NullPointerException e)
        {
            Logger.e(TAG,e.getMessage());
            OnActionFail(listener,e);
        }

    }

    @Override
    public void get(String key,OnEventListener listener) {

        try{
            byte[] value=mCache.get(key);
            CacheEvent event=new CacheEvent();
            event.key=key;
            event.action=CacheEvent.ACTION_GET;
            event.value=value;
            if(listener!=null)
                listener.onEventSucc(event);
        }catch (NullPointerException e)
        {
            Logger.d(TAG,e.getMessage());
            listener.onEventFail(e);
        }
    }

    @Override
    public void clear(OnEventListener listener) {
        try {
            init();
            CacheEvent event=new CacheEvent();
            event.action=CacheEvent.ACTION_CLEAR;
        }catch (Exception e)
        {
            Logger.e(TAG,e.getMessage());
            listener.onEventFail(e);
        }
    }

    @Override
    public void remove(String key,OnEventListener listener) {
        try
        {
            byte[] value=mCache.remove(key);
            CacheEvent event=new CacheEvent();
            event.action=CacheEvent.ACTION_REMOVE;
            event.key=key;
            event.value=value;
            OnActionSucc(listener,event);

        }
        catch (NullPointerException e)
        {
            Logger.d(TAG,e.getMessage());
            OnActionFail(listener,e);
        }
    }

    @Deprecated
    @Override
    public void exist(String key, OnEventListener listener) {
    }

    /**
     * recommend to construct MemoryLruCache WITH Builder
     */
    public static class Builder
    {
        private int size=0;
        public Builder setMaxSize(int size)
        {
            this.size=size;
            return this;
        }
        public MemoryLruCache create()
        {
            Logger.d(TAG,"create");
            MemoryLruCache memoryLruCache=new MemoryLruCache();
            if(0==size)
            {
                //default size
                int maxMemory = (int) Runtime.getRuntime().maxMemory();
                size = maxMemory/8;
            }
            memoryLruCache.setMaxSize(size);
            memoryLruCache.init();
            return memoryLruCache;
        }
    }
}
